package com.tank.net.msg;

import com.tank.DirectionEnum;
import com.tank.GroupEnum;
import com.tank.Tank;
import com.tank.TankFrame;
import com.tank.net.Client;

import java.io.*;
import java.util.Objects;
import java.util.UUID;

/**
 * @author CaoBaoYin
 * @since 21/11/1 17:25
 */
public class TankJoinMsg extends Msg {
    // 4 + 4 + 1 + 4 + 4 + 16
    private int x, y;
    private boolean moving;
    private DirectionEnum dir;
    private GroupEnum group;
    private UUID id;

    public TankJoinMsg() {
    }

    public TankJoinMsg(int x, int y, boolean moving, DirectionEnum dir, GroupEnum group, UUID id) {
        this.x = x;
        this.y = y;
        this.moving = moving;
        this.dir = dir;
        this.group = group;
        this.id = id;
    }

    public TankJoinMsg(Tank tank) {
        this.x = tank.getX();
        this.y = tank.getY();
        this.moving = tank.isMoving();
        this.dir = tank.getDir();
        this.group = tank.getGroupEnum();
        this.id = tank.getId();
    }

    @Override
    public byte[] toBytes() {
        byte[] bytes = null;
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
             DataOutputStream dos = new DataOutputStream(baos);) {

            dos.writeInt(this.x);
            dos.writeInt(this.y);
            dos.writeBoolean(this.moving);
            dos.writeInt(this.dir.ordinal());// 枚举 values 的 index 角标
            dos.writeInt(this.group.ordinal());
            dos.writeLong(id.getMostSignificantBits()); // 网络中没有人用字符串传输。会造成数据量大 这是128位的uuid，字符串128个字节，long只用了16个字节
            dos.writeLong(id.getLeastSignificantBits());
            dos.flush();

            bytes = baos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return bytes;
    }

    @Override
    public void parse(byte[] bytes) {
        try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
             DataInputStream dis = new DataInputStream(bis)) {
            this.x = dis.readInt();
            this.y = dis.readInt();// 因为我们先写的x后写的y
            this.moving = dis.readBoolean();
            this.dir = DirectionEnum.values()[dis.readInt()];
            this.group = GroupEnum.values()[dis.readInt()];
            this.id = new UUID(dis.readLong(), dis.readLong());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void handle() {
        TankFrame tf = TankFrame.INSTANCE;
        if (tf.tankMap.containsKey(this.getId())) return;

        tf.tankMap.put(this.getId(), new Tank(this.getX(), this.getY(), this.getDir(), this.getGroupEnum(), tf));

        Client.INSTANCE.sendMsg(new TankJoinMsg(tf.getMainTank()));
    }

    @Override
    public MsgTypeEnum getMsgType() {
        return MsgTypeEnum.TANK_JOIN;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public boolean isMoving() {
        return moving;
    }

    public void setMoving(boolean moving) {
        this.moving = moving;
    }

    public DirectionEnum getDir() {
        return dir;
    }

    public void setDir(DirectionEnum dir) {
        this.dir = dir;
    }

    public GroupEnum getGroupEnum() {
        return group;
    }

    public void setGroupEnum(GroupEnum group) {
        this.group = group;
    }

    public UUID getId() {
        return id;
    }

    public void setId(UUID id) {
        this.id = id;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof TankJoinMsg)) return false;
        TankJoinMsg that = (TankJoinMsg) o;
        return getX() == that.getX() &&
                getY() == that.getY() &&
                isMoving() == that.isMoving() &&
                getDir() == that.getDir() &&
                group == that.group &&
                Objects.equals(getId(), that.getId());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getX(), getY(), isMoving(), getDir(), group, getId());
    }

    @Override
    public String toString() {
        return "TankJoinMsg{" +
                "x=" + x +
                ", y=" + y +
                ", moving=" + moving +
                ", dir=" + dir +
                ", group=" + group +
                ", id=" + id +
                '}';
    }
}
